﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace HideAndSeek
{
    public partial class Form1 : Form
    {
        //variable references to keep track of each room in the haouse
        RoomWithDoor livingRoom;
        RoomWithDoor kitchen;
        RoomWithHidingPlace dinningRoom;
        OutsideWithDoor frontYard;
        OutsideWithDoor backYard;
        Room stairs;
        RoomWithHidingPlace upstairsHallway;
        RoomWithHidingPlace masterBedroom;
        RoomWithHidingPlace secondBedroom;
        RoomWithHidingPlace bathroom;
        OutsideWithHidingPlace driveway;
        OutsideWithHidingPlace garden;
        
        Opponent opponent;

        int Moves = 0;

        //this is how the form keeps track of which room is being displayed
        Location currentLocation; 

        public Form1()
        {
            InitializeComponent();
            //creates the object and set the first room to visit
            CreateObjects();
            opponent = new Opponent(frontYard);
            ResetGame(false);
        }

        private void CreateObjects()
        {

            //instanciates the object and passes the right information to each constructor
            livingRoom = new RoomWithDoor("Living Room", "an antique carpet", 
                    "an oak door with a brass knob leading to the front yard","inside the closet");
            kitchen  = new RoomWithDoor("Kitchen", "stainless steel appliances", 
                    "screen door leading to the back yard","in the cabinet");
            dinningRoom = new RoomWithHidingPlace("Dinning Room", "crystal chandelier","in the tall armoire");
            frontYard = new OutsideWithDoor("Front Yard", false, 
                    "an oak door with a brass knob leading to the living room");
            backYard = new OutsideWithDoor("Back Yard", true, "screen door leading to the kitchen");
            stairs = new Room("Stairs", "Wooden bannister");
            upstairsHallway = new RoomWithHidingPlace("Upstairs Hallway", "a picture of a dog", "in the closet");
            masterBedroom = new RoomWithHidingPlace("Master Bedroom", "a Large bed", "under the bed");
            secondBedroom = new RoomWithHidingPlace("Second Bedroom", "a small bed", "under the bed");
            bathroom = new RoomWithHidingPlace("Bathroom", "a sink and a toilet", "in the shower");
            driveway = new OutsideWithHidingPlace("Driveway", false, "in the garage");
            garden = new OutsideWithHidingPlace("Garden", false, "in the shed");

            //populate the Exits array for each instance
            livingRoom.Exits = new Location[] {dinningRoom,stairs};
            kitchen.Exits = new Location[] {dinningRoom};
            dinningRoom.Exits = new Location[] { livingRoom, kitchen };
            frontYard.Exits = new Location[] { garden,driveway };
            backYard.Exits = new Location[] { garden,driveway };
            stairs.Exits = new Location[] { livingRoom, upstairsHallway };
            upstairsHallway.Exits = new Location[] { stairs, masterBedroom, secondBedroom, bathroom };
            masterBedroom.Exits = new Location[] { upstairsHallway };
            secondBedroom.Exits = new Location[] { upstairsHallway };
            bathroom.Exits = new Location[] { upstairsHallway };
            driveway.Exits = new Location[] { frontYard, backYard };
            garden.Exits = new Location[] { backYard, frontYard };

            //set the door location for those who has exterior door
            livingRoom.DoorLocation = frontYard;
            frontYard.DoorLocation = livingRoom;
            kitchen.DoorLocation = backYard;
            backYard.DoorLocation = kitchen;

        }

        private void MoveToANewLoaction(Location newLocation)
        {
            Moves++;
            currentLocation = newLocation;
            RedrawForm();
        }

        private void RedrawForm()
        {
            exits.Items.Clear();
            for (int i = 0; i < currentLocation.Exits.Length; i++)
            {
                exits.Items.Add(currentLocation.Exits[i].Name);
            }
            exits.SelectedIndex = 0;
            description.Text = currentLocation.Description + "\r\n( move # " + Moves + " )";
            if (currentLocation is IHasExteriorDoor)
            {
                goThroughTheDoor.Enabled = true;
            }
            else goThroughTheDoor.Enabled = false;
            if (currentLocation is IHidingPlace)
            {
                IHidingPlace locationTocheck = currentLocation as IHidingPlace;
                check.Enabled = true;
                check.Text = "Check " + locationTocheck.HidingPlace;
            }
            else
            {
                check.Text = "Check";
                check.Enabled = false;
            }
        }

        private void ResetGame(bool displayMessage)
        {
            hide.Enabled = true;
            goHere.Enabled = false;
            goThroughTheDoor.Enabled = false;
            check.Enabled = false;
            exits.Enabled = false;
            if (displayMessage) 
            { 
                MessageBox.Show("You found me in " + Moves + " moves!");
                IHidingPlace foundLocation = currentLocation as IHidingPlace;
                description.Text = "You found your opponent in #" + Moves + " moves!\r\n"
                    + "He was hiding " + foundLocation.HidingPlace+".";
            }
            Moves = 0;
        }

        private void goHere_Click(object sender, EventArgs e)
        {
            MoveToANewLoaction(currentLocation.Exits[exits.SelectedIndex]);
        }

        private void goThroughTheDoor_Click(object sender, EventArgs e)
        {
            IHasExteriorDoor hasDoor = currentLocation as IHasExteriorDoor;
            MoveToANewLoaction(hasDoor.DoorLocation);
        }

        private void check_Click(object sender, EventArgs e)
        {
            Moves++;
            if (opponent.Check(currentLocation))
            {
                ResetGame(true);
            } 
            else
            {
                RedrawForm();
            }
        }

        private void hide_Click(object sender, EventArgs e)
        {
            hide.Enabled=false;

            for (int i = 1; i <= 10; i++)
            {
                opponent.Move();
                description.Text = i + "....";
                Application.DoEvents();
                System.Threading.Thread.Sleep(750);
            }

            description.Text = "Ready or not, here I come!!!";
            Application.DoEvents();
            System.Threading.Thread.Sleep(750);

            goHere.Enabled = true;
            exits.Enabled = true;
            MoveToANewLoaction(livingRoom);
        }
    }
}
